package com.iplant.ams.controller.ams;

import com.iplant.ams.service.basicenum.ams.AMSFixedAssetsType;
import com.iplant.ams.service.po.ams.asset.AMSAssetInfo;
import com.iplant.ams.service.po.ams.fxt.AMSFrockTool;
import com.iplant.ams.service.po.ams.fxt.AMSMeasureTool;
import com.iplant.ams.service.po.ams.fxt.DMSMeasureLedger;
import com.iplant.ams.service.po.dms.DMSDeviceLedger;
import com.iplant.ams.service.po.dms.DMSDeviceModel;
import com.iplant.ams.service.po.ams.fxt.DMSFrockLedger;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.utils.RetCode;
import com.iplant.base.utils.annotation.trace.TraceAPI;
import com.iplant.base.utils.annotation.trace.TraceModuleAPI;
import com.iplant.base.utils.serializer.CloneTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.orm.ORMUtils;
import com.iplant.base.utils.sql.orm.PoService;
import com.iplant.basic.controller.BasicController;
import com.iplant.basic.service.po.bms.BMSEmployee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@TraceModuleAPI("资产列表")
@RestController
@RequestMapping("/api/AMSAssetInfo")
public class AMSAssetInfoController extends BasicController<AMSAssetInfo> {

    private static Logger logger = LoggerFactory.getLogger(AMSAssetInfoController.class);


    PoService<DMSFrockLedger> FrockLedgerService;
    PoService<AMSFrockTool> FrockToolService;

    PoService<DMSMeasureLedger> MeasureLedgerService;
    PoService<AMSMeasureTool> MeasureToolService;
    PoService<DMSDeviceLedger> DeviceLedgerService;

    PoService<DMSDeviceModel> DeviceModelService;


    public AMSAssetInfoController() {
        super(AMSAssetInfo.class);

        FrockLedgerService = ORMUtils.GetPoService(DMSFrockLedger.class);
        FrockToolService = ORMUtils.GetPoService(AMSFrockTool.class);
        DeviceLedgerService = ORMUtils.GetPoService(DMSDeviceLedger.class);
        DeviceModelService = ORMUtils.GetPoService(DMSDeviceModel.class);


        MeasureLedgerService = ORMUtils.GetPoService(DMSMeasureLedger.class);
        MeasureToolService = ORMUtils.GetPoService(AMSMeasureTool.class);
    }


    /**
     * 新增或更新
     */
    @TraceAPI(value = "新增或更新")
    @PostMapping("/Update")
    public Object Update(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Object wResult;
        try {
            BMSEmployee wLoginUser = GetSession(request);

            boolean wIsAdd = wParam.containsKey("ID") && StringUtils.parseInt(wParam.get("ID")) == 0;

            ServiceResult<AMSAssetInfo> wServiceResult = mPoService.UpdateSelectPo(wLoginUser, wParam);

            if (wServiceResult != null && StringUtils.isEmpty(wServiceResult.getFaultCode())
                    && wServiceResult.Result != null && wServiceResult.Result.ID > 0
                    && wIsAdd) {
                ServiceResult<Integer> wServiceResultInt;
                Map<String, Object> wParasMap;
                switch (AMSFixedAssetsType.getEnumType(wServiceResult.Result.TypeEnum)) {


                    case Device:
                        DMSDeviceModel wDMSDeviceModel = new DMSDeviceModel();
                        wDMSDeviceModel.Name = "默认";
                        wDMSDeviceModel.ID = 1;
                        wParasMap = new HashMap<>();
                        wParasMap.put("StandardModelID", wServiceResult.Result.StandardModelID);
                        ServiceResult<List<DMSDeviceModel>> wDMSDeviceModelServiceResult =
                                DeviceModelService.SelectPOList(wLoginUser, wParasMap,
                                        Pagination.getNewMaxSize());
                        if (wDMSDeviceModelServiceResult != null && wDMSDeviceModelServiceResult.Result != null && wDMSDeviceModelServiceResult.Result.size() > 0) {
                            wDMSDeviceModel = wDMSDeviceModelServiceResult.Result.get(0);
                        }
                        DMSDeviceLedger wDMSDeviceLedger = new DMSDeviceLedger(wServiceResult.Result, wDMSDeviceModel);
                        wDMSDeviceLedger.setUserInfo(wLoginUser);


                        wServiceResultInt =
                                DeviceLedgerService.UpdatePo(wLoginUser, wDMSDeviceLedger);
                        if (StringUtils.isNotEmpty(wServiceResultInt.getFaultCode())) {
                            wServiceResult.FaultCode += wServiceResultInt.getFaultCode();
                        }
                        break;
                    case Frock:
                        AMSFrockTool wAMSFrockTool = new AMSFrockTool();
                        wAMSFrockTool.Name = "默认";
                        wAMSFrockTool.ID = 1;
                        wParasMap = new HashMap<>();
                        wParasMap.put("StandardModelID", wServiceResult.Result.StandardModelID);
                        ServiceResult<List<AMSFrockTool>> wFrockToolServiceResult =
                                FrockToolService.SelectPOList(wLoginUser, wParasMap,
                                        Pagination.getNewMaxSize());
                        if (wFrockToolServiceResult != null && wFrockToolServiceResult.Result != null && wFrockToolServiceResult.Result.size() > 0) {
                            wAMSFrockTool = wFrockToolServiceResult.Result.get(0);
                        }
                        DMSFrockLedger wDMSFrockLedger = new DMSFrockLedger(wServiceResult.Result, wAMSFrockTool);
                        wDMSFrockLedger.setUserInfo(wLoginUser);


                        wServiceResultInt =
                                FrockLedgerService.UpdatePo(wLoginUser, wDMSFrockLedger);
                        if (StringUtils.isNotEmpty(wServiceResultInt.getFaultCode())) {
                            wServiceResult.FaultCode += wServiceResultInt.getFaultCode();
                        }
                        break;
                    case Measure:
                        AMSMeasureTool wAMSMeasureTool = new AMSMeasureTool();
                        wAMSMeasureTool.Name = "默认";
                        wAMSMeasureTool.ID = 1;
                        wParasMap = new HashMap<>();
                        wParasMap.put("StandardModelID", wServiceResult.Result.StandardModelID);
                        ServiceResult<List<AMSMeasureTool>> wMeasureToolServiceResult =
                                MeasureToolService.SelectPOList(wLoginUser, wParasMap,
                                        Pagination.getNewMaxSize());
                        if (wMeasureToolServiceResult != null && wMeasureToolServiceResult.Result != null && wMeasureToolServiceResult.Result.size() > 0) {
                            wAMSMeasureTool = wMeasureToolServiceResult.Result.get(0);
                        }
                        DMSMeasureLedger wDMSMeasureLedger = new DMSMeasureLedger(wServiceResult.Result, wAMSMeasureTool);
                        wDMSMeasureLedger.setUserInfo(wLoginUser);


                        wServiceResultInt =
                                MeasureLedgerService.UpdatePo(wLoginUser, wDMSMeasureLedger);
                        if (StringUtils.isNotEmpty(wServiceResultInt.getFaultCode())) {
                            wServiceResult.FaultCode += wServiceResultInt.getFaultCode();
                        }
                        break;
                    case Default:
                        break;
                }


            }


            if (StringUtils.isEmpty(wServiceResult.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "", null, wServiceResult.getResult());
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }


    /**
     * 新增或更新
     */
    @TraceAPI("批量新增或更新")
    @PostMapping("/UpdateList")
    public Object UpdateList(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Object wResult;
        try {
            BMSEmployee wLoginUser = GetSession(request);

            // ServiceResult<List<AMSAssetStandardModel>> wServiceResult = mPoService.UpdatePoList(wLoginUser, wParam);
            //成功后插入设备型号
            //默认使用设备类型第一个激活的
            if (!wParam.containsKey("data")) {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);
                return wResult;
            }
            List<AMSAssetInfo> wList = CloneTool.CloneArray(wParam.get("data"), AMSAssetInfo.class);
            Map<Integer, DMSDeviceModel> wDMSDeviceModelMap = new HashMap<>();

            ServiceResult<List<DMSDeviceModel>> wDMSDeviceModelServiceResult =
                    DeviceModelService.SelectPOList(wLoginUser, null,
                            Pagination.getNewMaxSize());
            if (wDMSDeviceModelServiceResult != null && wDMSDeviceModelServiceResult.Result != null && wDMSDeviceModelServiceResult.Result.size() > 0) {
                wDMSDeviceModelMap =
                        wDMSDeviceModelServiceResult.Result.stream().collect(Collectors.toMap(DMSDeviceModel::getStandardModelID, Function.identity(), (o1, o2) -> o2));
            }

            Map<Integer, AMSFrockTool> wAMSFrockToolMap = new HashMap<>();

            ServiceResult<List<AMSFrockTool>> wAMSFrockToolServiceResult =
                    FrockToolService.SelectPOList(wLoginUser, null,
                            Pagination.getNewMaxSize());
            if (wAMSFrockToolServiceResult != null && wAMSFrockToolServiceResult.Result != null && wAMSFrockToolServiceResult.Result.size() > 0) {
                wAMSFrockToolMap =
                        wAMSFrockToolServiceResult.Result.stream().collect(Collectors.toMap(AMSFrockTool::getStandardModelID, Function.identity(), (o1, o2) -> o2));
            }

            Map<Integer, AMSMeasureTool> wAMSMeasureToolMap = new HashMap<>();

            ServiceResult<List<AMSMeasureTool>> wAMSMeasureToolServiceResult =
                    MeasureToolService.SelectPOList(wLoginUser, null,
                            Pagination.getNewMaxSize());
            if (wAMSMeasureToolServiceResult != null && wAMSMeasureToolServiceResult.Result != null && wAMSMeasureToolServiceResult.Result.size() > 0) {
                wAMSMeasureToolMap =
                        wAMSMeasureToolServiceResult.Result.stream().collect(Collectors.toMap(AMSMeasureTool::getStandardModelID, Function.identity(), (o1, o2) -> o2));
            }


            ServiceResult<AMSAssetInfo> wAMSAssetInfoServiceResult = new ServiceResult<>();

            AMSAssetInfo wAssetInfo;

            ServiceResult<Integer> wServiceResult = new ServiceResult<>();
            DMSDeviceLedger wDMSDeviceLedger;
            DMSFrockLedger wDMSFrockLedger;

            DMSMeasureLedger wDMSMeasureLedger;
            for (AMSAssetInfo wAMSAssetInfo : wList) {

                wAMSAssetInfo.setUserInfo(wLoginUser);
                wAMSAssetInfoServiceResult = mPoService.UpdateSelectPo(wLoginUser, wAMSAssetInfo);

                if (StringUtils.isNotEmpty(wAMSAssetInfoServiceResult.getFaultCode())) {
                    wServiceResult.FaultCode += wAMSAssetInfoServiceResult.getFaultCode();
                    break;
                }
                if (wAMSAssetInfoServiceResult.Result == null || wAMSAssetInfoServiceResult.Result.ID <= 0) {
                    continue;
                }
                wAssetInfo = wAMSAssetInfoServiceResult.Result;

                switch (AMSFixedAssetsType.getEnumType(wAssetInfo.TypeEnum)) {


                    case Device:
                        if (!wDMSDeviceModelMap.containsKey(wAssetInfo.StandardModelID))
                            continue;

                        wDMSDeviceLedger = new DMSDeviceLedger(wAssetInfo, wDMSDeviceModelMap.get(wAssetInfo.StandardModelID));
                        wDMSDeviceLedger.setUserInfo(wLoginUser);
                        wServiceResult = DeviceLedgerService.UpdateCheckPo(wLoginUser, wDMSDeviceLedger);
                        break;
                    case Frock:
                        if (!wAMSFrockToolMap.containsKey(wAssetInfo.StandardModelID))
                            continue;

                        wDMSFrockLedger = new DMSFrockLedger(wAssetInfo, wAMSFrockToolMap.get(wAssetInfo.StandardModelID));
                        wDMSFrockLedger.setUserInfo(wLoginUser);
                        wServiceResult = FrockLedgerService.UpdateCheckPo(wLoginUser, wDMSFrockLedger);
                        break;
                    case Measure:
                        if (!wAMSMeasureToolMap.containsKey(wAssetInfo.StandardModelID))
                            continue;

                        wDMSMeasureLedger = new DMSMeasureLedger(wAssetInfo, wAMSMeasureToolMap.get(wAssetInfo.StandardModelID));
                        wDMSMeasureLedger.setUserInfo(wLoginUser);
                        wServiceResult = MeasureLedgerService.UpdateCheckPo(wLoginUser, wDMSMeasureLedger);
                        break;
                    case Default:
                        break;
                }

                if (StringUtils.isNotEmpty(wServiceResult.getFaultCode())) {
                    break;
                }

            }


            if (StringUtils.isEmpty(wServiceResult.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "", wList, null);
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }


    /**
     * 批量删除
     */
    @TraceAPI("批量删除")
    @PostMapping("/DeleteList")
    public Object DeleteList(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Object wResult;
        try {
            BMSEmployee wLoginUser = GetSession(request);

            // ServiceResult<List<AMSAssetStandardModel>> wServiceResult = mPoService.UpdatePoList(wLoginUser, wParam);
            //成功后插入设备型号
            //默认使用设备类型第一个激活的
            if (!wParam.containsKey("data")) {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);
                return wResult;
            }
            List<AMSAssetInfo> wList = CloneTool.CloneArray(wParam.get("data"), AMSAssetInfo.class);

            ServiceResult<Integer> wAMSAssetInfoServiceResult = new ServiceResult<>();

            ServiceResult<Integer> wServiceResult = new ServiceResult<>();
            Map<String, Object> wParams = new HashMap<>();
            for (AMSAssetInfo wAMSAssetInfo : wList) {
                wParams.clear();
                if (wAMSAssetInfo == null || wAMSAssetInfo.ID <= 0)
                    continue;
                wParams.put("AssetInfoID", wAMSAssetInfo.ID);


                switch (AMSFixedAssetsType.getEnumType(wAMSAssetInfo.TypeEnum)) {

                    case Device:
                        DeviceLedgerService.Delete(wLoginUser, wParams, " AND ID>0 ");
                        break;
                    case Frock:
                        FrockLedgerService.Delete(wLoginUser, wParams, " AND ID>0 ");
                        break;
                    case Measure:
                        MeasureLedgerService.Delete(wLoginUser, wParams, " AND ID>0 ");
                        break;
                    case Default:
                        break;
                }

                wAMSAssetInfoServiceResult = mPoService.DeletePO(wLoginUser, wAMSAssetInfo);

                if (StringUtils.isNotEmpty(wAMSAssetInfoServiceResult.getFaultCode())) {
                    wServiceResult.FaultCode += wAMSAssetInfoServiceResult.getFaultCode();
                }
            }


            if (StringUtils.isEmpty(wServiceResult.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "");
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }


    /**
     * 批量删除
     */
    @TraceAPI("删除")
    @PostMapping("/Delete")
    public Object Delete(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Object wResult;
        try {
            BMSEmployee wLoginUser = GetSession(request);

            // ServiceResult<List<AMSAssetStandardModel>> wServiceResult = mPoService.UpdatePoList(wLoginUser, wParam);
            //成功后插入设备型号
            //默认使用设备类型第一个激活的
            if (!wParam.containsKey("data")) {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);
                return wResult;
            }
            AMSAssetInfo wAMSAssetInfo = CloneTool.Clone(wParam.get("data"), AMSAssetInfo.class);


            Map<String, Object> wParams = new HashMap<>();

            wParams.put("AssetInfoID", wAMSAssetInfo.ID);


            switch (AMSFixedAssetsType.getEnumType(wAMSAssetInfo.TypeEnum)) {

                case Device:
                    DeviceLedgerService.Delete(wLoginUser, wParams, " AND ID>0 ");
                    break;
                case Frock:
                    FrockLedgerService.Delete(wLoginUser, wParams, " AND ID>0 ");
                    break;
                case Measure:
                    MeasureLedgerService.Delete(wLoginUser, wParams, " AND ID>0 ");
                    break;
                case Default:
                    break;
            }

            ServiceResult<Integer> wServiceResult = mPoService.DeletePO(wLoginUser, wAMSAssetInfo);


            if (StringUtils.isEmpty(wServiceResult.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "");
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }
}
